package com.imax.center.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.imax.center.constant.QueueConstant;
import com.imax.center.entity.SensorEventData;
import com.imax.center.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Component
@Slf4j
public class DeviceDataServiceImpl implements DeviceDataService {

    @Value("${tcp.log.enable}")
    private boolean logEnable;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    SensorEventDataService sensorEventDataService;

    /**
    * 使用异步，不会组赛响应设备
    * */
    @Async
    @Override
    public CompletableFuture<Boolean> asyncHandlerEvent(String message, Map<String, Object> data) {
        this.eventHandler(message, data);
        return CompletableFuture.completedFuture(true);
    }

    @Override
    public void syncHandlerEvent(String message, Map<String, Object> data) {
        this.eventHandler(message, data);
    }

    private void eventHandler(String message, Map<String, Object> data) {
        try {
            if (logEnable) {
                log.info("接收到设备数据:{}", message);
            }
            //判断是否已存在
            if (this.isExist(data)) {
                log.info("数据已存在，不进行处理。{}", message);
                return;
            }
            //数据写入到MQ
            rabbitTemplate.convertAndSend(QueueConstant.EXCHANGE_NAME, QueueConstant.ROUTING_KEY, message);
            //数据写入到数据库
            this.addEventDataToCenterDb(message, data);
            if (logEnable) {
                log.info("数据写入MQ和数据库成功");
            }
        } catch (Exception e) {
            log.error("数据写入到MQ失败:{}", e.getMessage());
        }
    }

    //判断是否已存在
    private boolean isExist(Map<String, Object> data) {
        String mn = data.get("MN").toString();
        String cn = data.get("CN").toString();
        Map<String, Object> cpMap = this.getCpData(data.get("CP"));
        String dataTime = (String) cpMap.get("DataTime");
        //构建查询器
        LambdaQueryWrapper<SensorEventData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SensorEventData::getMn, mn);
        queryWrapper.eq(SensorEventData::getCn, cn);
        queryWrapper.eq(SensorEventData::getUpTime, this.formatDataTime(dataTime));
        //查询是否存在
        int count = sensorEventDataService.count(queryWrapper);
        return count > 0;
    }

    private boolean addEventDataToCenterDb(String message, Map<String, Object> data) {
        //data判空
        if (data == null || data.isEmpty()) {
            return true;
        }
        try {
            if (data.get("CN") != null && data.get("CN") == "2021") {
                //2021类型数据为设备运行状态，不保存
                return true;
            }
            Map<String, String> cnMap = new HashMap<>();
            cnMap.put("2011", "实时数据");
            cnMap.put("2051", "分钟数据");
            cnMap.put("2061", "小时数据");
            cnMap.put("2031", "日数据");
            Map<String, Object> cpMap = this.getCpData(data.get("CP"));
            Double w00000Rtd = (Double) cpMap.get("w00000-Rtd"); //流量瞬时值
            Double w00000Avg = (Double) cpMap.get("w00000-Avg"); //流量平均值
            Double w00000Cou = (Double) cpMap.get("w00000-Cou"); //流量累积值
            SensorEventData vo = new SensorEventData();
            //字段赋值，字段判空处理
            vo.setSt(data.get("ST") != null ? data.get("ST").toString() : null);
            vo.setMn(data.get("MN") != null ? data.get("MN").toString() : null);
            vo.setHeader(data.get("Header") != null ? data.get("Header").toString() : null);
            vo.setPw(data.get("PW") != null ? data.get("PW").toString() : null);
            vo.setDataLength(data.get("DataLength") != null ? data.get("DataLength").toString() : null);
            vo.setCn(data.get("CN") != null ? data.get("CN").toString() : null);
            vo.setCnText(data.get("CN") != null ? cnMap.get(data.get("CN").toString()) : null);
            vo.setQn(data.get("QN") != null ? data.get("QN").toString() : null);
            vo.setFlag(data.get("Flag") != null ? data.get("Flag").toString() : null);
            vo.setCp(data.get("CP") != null ? JSONObject.toJSONString(data.get("CP")) : null);
            vo.setCrc16(data.get("CRC16") != null ? data.get("CRC16").toString() : null );
            vo.setEventData(JSONObject.toJSONString(data));
            vo.setEventDataStr(message);
            vo.setUpTime(this.formatDataTime((String)cpMap.get("DataTime")));
            vo.setCreateTime(LocalDateTime.now());
            vo.setW00000Rtd(w00000Rtd);
            vo.setW00000Avg(w00000Avg);
            vo.setW00000Cou(w00000Cou);
            //保存到数据库
            return sensorEventDataService.save(vo);
        } catch (Exception e) {
            log.error("add eventData to db error", e);
            return false;
        }
    }

    private Map<String, Object> getCpData(Object cpObj) {
        Map<String, Object> cpMap = null;
        if (cpObj instanceof Map) {
            cpMap = (Map<String, Object>) cpObj;
        } else if (cpObj instanceof String) {
            cpMap = JSONObject.parseObject((String) cpObj);
        } else {
            log.error("CP数据格式异常: {}", cpObj);
        }
        return cpMap;
    }

    private LocalDateTime formatDataTime(String val) {
        //"20250520220405"转为"yyyy/MM/dd HH:mm:ss"
        if (StrUtil.isBlank(val) || val.length() != 14) {
            return LocalDateTime.now();
        }
        // 输入格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        return LocalDateTime.parse(val, inputFormatter);
    }

}
